home *** CD-ROM | disk | FTP | other *** search
/ Network CD 2 / Network CD - Volume 2.iso / programs / internet / tcp / amitcp / amitcp-src-22.lha / AmiTCP-2.2 / src / appl / finger / lprint.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-14  |  8.9 KB  |  336 lines

  1. RCS_ID_C = "$Id: lprint.c,v 6.2 93/10/15 03:00:11 ppessi Exp $";
  2.  
  3. /*
  4.  * lprint.c - print finger information in long format
  5.  *
  6.  * Copyright © 1993 AmiTCP/IP Group, <AmiTCP-group@hut.fi>
  7.  *                  Helsinki University of Technology, Finland.
  8.  *
  9.  * This program is derived from original work distributed in BSD Net 2.
  10.  *
  11.  * Created      : Fri Oct 15 01:29:07 1993 ppessi
  12.  * Last modified: Fri Oct 15 01:32:34 1993 ppessi
  13.  *
  14.  * $Log:    lprint.c,v $
  15.  * Revision 6.2  93/10/15  03:00:11  ppessi
  16.  * Polished AmiTCP support
  17.  * 
  18.  */
  19.  
  20. /* Copyright (c) 1989 The Regents of the University of California.
  21.  * All rights reserved.
  22.  *
  23.  * This code is derived from software contributed to Berkeley by
  24.  * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
  25.  *
  26.  * Redistribution and use in source and binary forms, with or without
  27.  * modification, are permitted provided that the following conditions
  28.  * are met:
  29.  * 1. Redistributions of source code must retain the above copyright
  30.  *    notice, this list of conditions and the following disclaimer.
  31.  * 2. Redistributions in binary form must reproduce the above copyright
  32.  *    notice, this list of conditions and the following disclaimer in the
  33.  *    documentation and/or other materials provided with the distribution.
  34.  * 3. All advertising materials mentioning features or use of this software
  35.  *    must display the following acknowledgement:
  36.  *    This product includes software developed by the University of
  37.  *    California, Berkeley and its contributors.
  38.  * 4. Neither the name of the University nor the names of its contributors
  39.  *    may be used to endorse or promote products derived from this software
  40.  *    without specific prior written permission.
  41.  *
  42.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  43.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  44.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  45.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  46.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  47.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  48.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  49.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  50.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  51.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  52.  * SUCH DAMAGE.
  53.  */
  54.  
  55. #include <sys/types.h>
  56. #if AMIGA
  57. #include <fcntl.h>
  58. #else
  59. #include <sys/file.h>
  60. #endif
  61. #include <sys/stat.h>
  62. #include <sys/time.h>
  63. #include <tzfile.h>
  64. #include <string.h>
  65. #include <stdlib.h>
  66. #include <stdio.h>
  67. #include <ctype.h>
  68. #if !AMIGA
  69. #include <paths.h>
  70. #endif
  71. #include "finger.h"
  72.  
  73. #define    LINE_LEN    80
  74. #define    TAB_LEN        8        /* 8 spaces between tabs */
  75. #define    _PATH_PLAN    ".plan"
  76. #define    _PATH_PROJECT    ".project"
  77. #if AMIGA
  78. #define _PATH_BSHELL "CLI"
  79. #endif
  80.  
  81. void lprint(register PERSON *pn);
  82. int show_text(char *directory, char *file_name, char *header);
  83. int demi_print(char *str, int oddfield);
  84. void vputc(register int ch);
  85.  
  86. void
  87. lflag_print(void)
  88. {
  89.   extern int pplan;
  90.   register PERSON *pn;
  91.  
  92.   for (pn = phead;;) {
  93.     lprint(pn);
  94.     if (!pplan) {
  95.       (void)show_text(pn->dir, _PATH_PROJECT, "Project:");
  96.       if (!show_text(pn->dir, _PATH_PLAN, "Plan:"))
  97.     (void)printf("No Plan.\n");
  98.     }
  99.     if (!(pn = pn->next))
  100.       break;
  101.     putchar('\n');
  102.   }
  103. }
  104.  
  105. void
  106. lprint(register PERSON *pn)
  107. {
  108.   extern time_t now;
  109.   register struct tm *delta;
  110.   register WHERE *w;
  111.   register int cpr, len, maxlen;
  112.   struct tm *tp;
  113.   int oddfield;
  114.   time_t time();
  115.   char *t, *tzn, *prphone();
  116.  
  117.   /*
  118.    * long format --
  119.    *    login name
  120.    *    real name
  121.    *    home directory
  122.    *    shell
  123.    *    office, office phone, home phone if available
  124.    */
  125.   (void)printf("Login: %-15s\t\t\tName: %s\nDirectory: %-25s",
  126.            pn->name, pn->realname, pn->dir);
  127.   (void)printf("\tShell: %-s\n", *pn->shell ? pn->shell : _PATH_BSHELL);
  128.  
  129.   /*
  130.    * try and print office, office phone, and home phone on one line;
  131.    * if that fails, do line filling so it looks nice.
  132.    */
  133. #define    OFFICE_TAG        "Office"
  134. #define    OFFICE_PHONE_TAG    "Office Phone"
  135.   oddfield = 0;
  136.   if (pn->office && pn->officephone &&
  137.       strlen(pn->office) + strlen(pn->officephone) +
  138.       sizeof(OFFICE_TAG) + 2 <= 5 * TAB_LEN) {
  139.     (void)sprintf(tbuf, "%s: %s, %s", OFFICE_TAG, pn->office,
  140.           prphone(pn->officephone));
  141.     oddfield = demi_print(tbuf, oddfield);
  142.   } else {
  143.     if (pn->office) {
  144.       (void)sprintf(tbuf, "%s: %s", OFFICE_TAG, pn->office);
  145.       oddfield = demi_print(tbuf, oddfield);
  146.     }
  147.     if (pn->officephone) {
  148.       (void)sprintf(tbuf, "%s: %s", OFFICE_PHONE_TAG,
  149.             prphone(pn->officephone));
  150.       oddfield = demi_print(tbuf, oddfield);
  151.     }
  152.   }
  153.   if (pn->homephone) {
  154.     (void)sprintf(tbuf, "%s: %s", "Home Phone",
  155.           prphone(pn->homephone));
  156.     oddfield = demi_print(tbuf, oddfield);
  157.   }
  158.   if (oddfield)
  159.     putchar('\n');
  160.  
  161.   /*
  162.    * long format con't: * if logged in
  163.    *    terminal
  164.    *    idle time
  165.    *    if messages allowed
  166.    *    where logged in from
  167.    * if not logged in
  168.    *    when last logged in
  169.    */
  170.   /* find out longest device name for this user for formatting */
  171.   for (w = pn->whead, maxlen = -1; w != NULL; w = w->next)
  172.     if ((len = strlen(w->tty)) > maxlen)
  173.       maxlen = len;
  174.   /* find rest of entries for user */
  175.   for (w = pn->whead; w != NULL; w = w->next) {
  176.     switch (w->info) {
  177.     case LOGGEDIN:
  178.       tp = localtime(&w->loginat);
  179.       t = asctime(tp);
  180. #if HAVE_TZONE
  181.       tzn = tp->tm_zone;
  182. #else
  183.       tzn = getenv("TZ"); 
  184.       if (!tzn) tzn = "Local";
  185. #endif
  186.       cpr = printf("On since %.16s (%s) on %s",
  187.            t, tzn, w->tty);
  188.       /*
  189.        * idle time is tough; if have one, print a comma,
  190.        * then spaces to pad out the device name, then the
  191.        * idle time.  Follow with a comma if a remote login.
  192.        */
  193.       delta = gmtime(&w->idletime);
  194.       if (delta->tm_yday || delta->tm_hour || delta->tm_min) {
  195.     cpr += printf("%-*s idle ",
  196.               maxlen - strlen(w->tty) + 1, ",");
  197.     if (delta->tm_yday > 0) {
  198.       cpr += printf("%d day%s ",
  199.             delta->tm_yday,
  200.             delta->tm_yday == 1 ? "" : "s");
  201.     }
  202.     cpr += printf("%d:%02d",
  203.               delta->tm_hour, delta->tm_min);
  204.     if (*w->host) {
  205.       putchar(',');
  206.       ++cpr;
  207.     }
  208.       }
  209.       if (!w->writable)
  210.     cpr += printf(" (messages off)");
  211.       break;
  212.     case LASTLOG:
  213.       if (w->loginat == 0) {
  214.     (void)printf("Never logged in.");
  215.     break;
  216.       }
  217.       tp = localtime(&w->loginat);
  218.       t = asctime(tp);
  219. #if HAVE_TZONE
  220.       tzn = tp->tm_zone;
  221. #else
  222.       tzn = getenv("TZ");
  223.       if (!tzn) tzn = "Local";
  224. #endif
  225.       if (now - w->loginat > SECSPERDAY * DAYSPERNYEAR / 2)
  226.     cpr =
  227.       printf("Last login %.16s %.4s (%s) on %s",
  228.          t, t + 20, tzn, w->tty);
  229.       else
  230.     cpr = printf("Last login %.16s (%s) on %s",
  231.              t, tzn, w->tty);
  232.  
  233.       break;
  234.     }
  235.     if (*w->host) {
  236.       if (LINE_LEN < (cpr + 6 + strlen(w->host)))
  237.     (void)printf("\n   ");
  238.       (void)printf(" from %s", w->host);
  239.     }
  240.     putchar('\n');
  241.   }
  242. }
  243.  
  244. int
  245. demi_print(char *str, int oddfield)
  246. {
  247.   static int lenlast;
  248.   int lenthis, maxlen;
  249.  
  250.   lenthis = strlen(str);
  251.   if (oddfield) {
  252.     /*
  253.      * We left off on an odd number of fields.  If we haven't
  254.      * crossed the midpoint of the screen, and we have room for
  255.      * the next field, print it on the same line; otherwise,
  256.      * print it on a new line.
  257.      *
  258.      * Note: we insist on having the right hand fields start
  259.      * no less than 5 tabs out.
  260.      */
  261.     maxlen = 5 * TAB_LEN;
  262.     if (maxlen < lenlast)
  263.       maxlen = lenlast;
  264.     if (((((maxlen / TAB_LEN) + 1) * TAB_LEN) +
  265.      lenthis) <= LINE_LEN) {
  266.       while(lenlast < (4 * TAB_LEN)) {
  267.     putchar('\t');
  268.     lenlast += TAB_LEN;
  269.       }
  270.       (void)printf("\t%s\n", str); /* force one tab */
  271.     } else {
  272.       (void)printf("\n%s", str); /* go to next line */
  273.       oddfield = !oddfield;    /* this'll be undone below */
  274.     }
  275.   } else
  276.     (void)printf("%s", str);
  277.   oddfield = !oddfield;        /* toggle odd/even marker */
  278.   lenlast = lenthis;
  279.   return(oddfield);
  280. }
  281.  
  282. int
  283. show_text(char *directory, char *file_name, char *header)
  284. {
  285.   register int ch, lastc;
  286.   register FILE *fp;
  287.  
  288. #if AMIGA
  289.   {
  290.     char *dp = tbuf;
  291.     while (*dp = *directory++)
  292.       dp++;
  293.     if (dp[-1] != '/' && dp[-1] != ':')  
  294.       *dp++ = '/';
  295.     while (*dp++ = *file_name++)
  296.       ;
  297.   }
  298. #else
  299.   (void)sprintf(tbuf, "%s/%s", directory, file_name);
  300. #endif
  301.   if ((fp = fopen(tbuf, "r")) == NULL)
  302.     return(0);
  303.   (void)printf("%s\n", header);
  304.   while ((ch = getc(fp)) != EOF)
  305.     vputc(lastc = ch);
  306.   if (lastc != '\n')
  307.     (void)putchar('\n');
  308.   (void)fclose(fp);
  309.   return(1);
  310. }
  311.  
  312. void
  313. vputc(register int ch)
  314. {
  315. #if !AMIGA
  316.   int meta;
  317.  
  318.   if (!isascii(ch)) {
  319.     (void)putchar('M');
  320.     (void)putchar('-');
  321.     ch = toascii(ch);
  322.     meta = 1;
  323.   } else
  324.     meta = 0;
  325.   if (isprint(ch) || !meta && (ch == ' ' || ch == '\t' || ch == '\n'))
  326.     (void)putchar(ch);
  327. #else /* AMIGA */
  328.   if (isprint(ch) || (ch == ' ' || ch == '\t' || ch == '\n'))
  329.     (void)putchar(ch);
  330. #endif
  331.   else {
  332.     (void)putchar('^');
  333.     (void)putchar(ch == '\177' ? '?' : ch | 0100);
  334.   }
  335. }
  336.